{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "77ca6209",
   "metadata": {},
   "source": [
    "## Socket Programming in Python"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb0820a0",
   "metadata": {},
   "source": [
    "* Python provides two levels of access to network services. At a low level, you can access the basic socket support in the underlying operating system, which allows you to implement clients and servers for both connection-oriented and connectionless protocols.\n",
    "\n",
    "* Python also has libraries that provide higher-level access to specific application-level network protocols, such as FTP, HTTP, and so on.\n",
    "\n",
    "* This chapter gives you understanding on most famous concept in Networking - Socket Programming."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b651ba54",
   "metadata": {},
   "source": [
    "Sockets have a long history. Their use originated with ARPANET (Advanced Research Project Agency) in 1971 and later became an API in the Berkeley Software Distribution (BSD) operating system released in 1983 called Berkeley sockets.\n",
    "\n",
    "When the Internet took off in the 1990s with the World Wide Web, so did network programming. Web servers and browsers weren’t the only applications taking advantage of newly connected networks and using sockets. Client-server applications of all types and sizes came into widespread use.\n",
    "\n",
    "Today, although the underlying protocols used by the socket API have evolved over the years, and we’ve seen new ones, the low-level API has remained the same.\n",
    "\n",
    "The most common type of socket applications are client-server applications, where one side acts as the server and waits for connections from clients. This is the type of application that I’ll be covering in this tutorial. \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c150380c",
   "metadata": {},
   "source": [
    "* Socket programming is a way of connecting two nodes on a network to communicate with each other. One socket(node) listens on a particular port at an IP, while the other socket reaches out to the other to form a connection. The server forms the listener socket while the client reaches out to the server. \n",
    "\n",
    "* Sockets may be implemented over a number of different channel types: Unix domain sockets, TCP, UDP, and so on. The socket library provides specific classes for handling the common transports as well as a generic interface for handling the rest."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38900680",
   "metadata": {},
   "source": [
    "## TCP vs UDP\n",
    "\n",
    "The __Transmission Control Protocol (TCP)__ and __User Datagram Protocol (UDP)__ are the two most popular protocols in the transport layer. \n",
    "\n",
    "* They ensures that messages are delivered error-free, in sequence, and with no losses or duplication. \n",
    "\n",
    "* The key difference between TCP and UDP is that TCP provides a wide variety of services to applications, whereas UDP does not. At the result of this, TCP is much more complex than UDP so this tutorial is dedicated to explore TCP in detail but we still compare them.\n",
    "\n",
    "First, let's look at the TCP/IP model\n",
    "![打开方式](TCP_IP.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e282cc44",
   "metadata": {},
   "source": [
    "Both TCP and UDP are protocols at the Transport layer (of both OSI and TCP/IP model) but why we need both of them? The answer is:\n",
    "\n",
    "+ TCP is slower but reliable\n",
    "+ UDP is faster but unreliable\n",
    "\n",
    "In most cases we will want to be reliable in web accessing, email communicating, file uploading… as we don’t expect a few corrupted packets would destroy our whole work. With TCP, these corrupted packets will be resent or repaired to make sure everything is correct. Yes, TCP is really nice to ensure your work is accurate!\n",
    "\n",
    "__But with a price…__\n",
    "\n",
    "+ To guarantee the sending segments is free of error, TCP adds some bits __for tracking and checking purpose__ so that the other end can verify and ask for missing pieces of segments. \n",
    "* __As a result of this, the segments become larger, consume more bandwidth and CPU resources to proceed.__\n",
    "\n",
    "* Although UDP cannot guarantee everything is accurate like TCP but UDP is faster than TCP because it does not require additional bits for tracking and checking purpose. So which tasks need speed? Video (streaming) and audio are ideal for this task because they are considered real-time applications. Suppose you are talking to your friend, surely you want your voice to reach your friend without any delay. It would be very weird if your friend can only hear your voice after a few seconds.\n",
    "\n",
    "* TCP can also slow down the transmission if it sees the path to the destination is too crowded. You don’t want TCP to slow down your voice in traffic-jam hours either. For example when you say “Hello, how are you?”, your friend at the other end may hear “Hellooooo,…… hooooooooow arrrrrrrre yyyyyoou”. What is an awful conversation!\n",
    "\n",
    "* Losing a few packets for voice or video is acceptable. For example if you say the word “Hello” in one second, an IP phone generates about 25 to 100 packets (just an estimation, it depends on the codec and sampling frequency) so your friend can still understand what you say even if a few packets are missing. Moreover, re-transmission the missing packets is not useful as voice and video are real-time applications and the receiving end cannot wait for the missing segments to be resent."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5eb62213",
   "metadata": {},
   "source": [
    "So now we have some basic understanding of TCP and UDP. In the next part we will learn more about TCP. Let’s start with how TCP set up and terminate a connection.\n",
    "\n",
    "### TCP three-way handshake (to start the communication)\n",
    "\n",
    "Suppose host A （e.g., client) wants to start communicating with host B (e.g., server) using TCP. Before they can send real data, a three-way handshake must be established first. Let’s see how this process takes place:\n",
    "\n",
    "![打开方式](TCP_3shake_1.png)\n",
    "\n",
    "1. First host A will send a SYN message (a TCP segment with SYN flag set to 1, SYN is short for SYNchronize) to indicate it wants to setup a connection with host B. This message includes a sequence (SEQ) number for tracking purpose. This sequence number can be any 32-bit number (range from 0 to 232) so we use “x” to represent it.\n",
    "\n",
    "2. After receiving SYN message from host A, host B replies with SYN-ACK message (some books may call it “SYN/ACK” or “SYN, ACK” message. ACK is short for ACKnowledge). This message includes a SYN sequence number and an ACK number:\n",
    "+ SYN sequence number (let’s called it “y”) is a random number and does not have any relationship with Host A’s SYN SEQ number.\n",
    "+ ACK number is the next number of Host A’s SYN sequence number it received, so we represent it with “x+1”. It means “I received your part. Now send me the next part (x + 1)”.\n",
    "\n",
    "__The SYN-ACK message indicates host B accepts to talk to host A (via ACK part). And ask if host A still wants to talk to it as well (via SYN part).__\n",
    "\n",
    "3. After Host A received the SYN-ACK message from host B, it sends an ACK message with ACK number “y+1” to host B. This confirms host A still wants to talk to host B."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83a297f4",
   "metadata": {},
   "source": [
    "If you are still unclear about this process, let’s assign: x = 1 and y = 50:\n",
    "![打开方式](TCP_3shake_2.png)       "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef240cd0",
   "metadata": {},
   "source": [
    "In this process, three messages need to be sent so we often call it “three-way handshake”.\n",
    "\n",
    "Nice, now you really understand TCP three-way handshake, right? Host A can start sending real traffic to host B after the three-way handshake process.\n",
    "\n",
    "TCP also does nearly the same thing when one end wants to terminate the connection with TCP four-way termination process."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25fa8c8b",
   "metadata": {},
   "source": [
    "### TCP four-way termination (to end the communication)\n",
    "\n",
    "Suppose Host A wants to end the connection to host B, Host A will send a FIN message (a TCP segment with FIN flag set to 1), FIN is short for FINISH. The purpose of FIN message is to enable TCP to gracefully terminate an established connection. Host A then enters a state called the FIN-WAIT state. In FIN-WAIT state, Host A continues to receive TCP segments from Host B and proceed the segments already in the queue, but Host A will not send any additional data.\n",
    "\n",
    "Device B will confirm it has received the FIN message with an ACK (with sequence x+1). From this point, Host B will no longer accept data from Host A. Host B can continue sending data to Host A. If Host B does not have any more data to send, it will also terminate the connection by sending a FIN message. Host A will then ACK that segment and terminate the connection.\n",
    "![打开方式](TCP_4shake.png) \n",
    "\n",
    "\n",
    "TCP requires to establish and terminate the connection before and after exchanging real traffic so it is called __connection-oriented protocol__. UDP does not support these features so it is called __connectionless protocol.__"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5530926",
   "metadata": {},
   "source": [
    "## Sockets in Python\n",
    "\n",
    "In the diagram below, let’s look at the sequence of socket API calls and data flow for TCP:\n",
    "\n",
    "![打开方式](socket.jpeg) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b50a541a",
   "metadata": {},
   "source": [
    "### The socket Module\n",
    "To create a socket, you must use the socket.socket() function available in socket module, which has the general syntax −\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cb953537",
   "metadata": {},
   "outputs": [],
   "source": [
    "import socket\n",
    "s = socket.socket (socket_family, socket_type, protocol=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "884e4edf",
   "metadata": {},
   "source": [
    "Here is the description of the parameters −\n",
    "\n",
    "* __socket_family__ − This is either AF_UNIX or AF_INET, as explained earlier.\n",
    "\n",
    "* __socket_type__ − This is either SOCK_STREAM or SOCK_DGRAM.\n",
    "\n",
    "* __protocol__ − Typically zero, this may be used to identify a variant of a protocol within a domain and type\n",
    "\n",
    "Once you have socket object, then you can use required functions to create your client or server program. Following is the list of functions required −\n",
    "\n",
    "### Server Socket Methods\n",
    "* __s.bind()__: This method binds address (hostname, port number pair) to socket.\n",
    "* __s.listen()__: This method sets up and start TCP listener.\n",
    "* __s.accept()__: This passively accept TCP client connection, waiting until connection arrives (blocking).\n",
    "\n",
    "### Client Socket Methods\n",
    "* __s.connect()__: This method actively initiates TCP server connection.\n",
    "\n",
    "### General Socket Methods\n",
    "* __s.recv()__: This method receives TCP message\n",
    "* __s.send()__: This method transmits TCP message\n",
    "* __s.recvfrom()__: This method receives UDP message\n",
    "* __s.sendto()__: This method transmits UDP message\n",
    "* __s.close()__: This method closes socket\n",
    "* __socket.gethostname()__: Returns the hostname"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ab2521a",
   "metadata": {},
   "source": [
    "__see examply on Spyder__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c1aa13a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
